package cn.mengfly.fxtest.app;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @author Mengfly
 */
public class BindingSelectApp extends Application {

    @Data
    @AllArgsConstructor
    public static class Rating {
        private Float value;
        private Float scale;
    }

    @Data
    @AllArgsConstructor
    public static class Track {
        private String artist;
        private String album;
        private String track;
        private Integer trackNo;
        private Rating rating;
        private Boolean downloaded;
    }

    private final Track currentTrack = new Track(
            "Jaco Pastorius",
            "Jaco Pastorius",
            "Come On, Come Over",
            2,
            new Rating(4.99f, 5.00f),
            false
    );

    private final TextField tfArtist = new TextField();
    private final TextField tfAlbum = new TextField();
    private final TextField tfTrack = new TextField();
    private final TextField tfTrackNo = new TextField();
    private final TextField tfRating = new TextField();
    private final TextField tfDownloaded = new TextField();

    private final Button downloadButton = new Button("Download");

    private final BooleanProperty downloaded = new SimpleBooleanProperty(currentTrack, "downloaded");

    @Override
    public void start(Stage primaryStage) {
        GridPane gp = new GridPane();

        gp.add(new Label("Artist"), 0, 0);
        gp.add(tfArtist, 1, 0);
        gp.add(new Label("Album"), 0, 1);
        gp.add(tfAlbum, 1, 1);
        gp.add(new Label("Track"), 0, 2);
        gp.add(tfTrack, 1, 2);
        gp.add(new Label("#"), 0, 3);
        gp.add(tfTrackNo, 1, 3);
        gp.add(new Label("Rating"), 0, 4);
        gp.add(tfRating, 1, 4);
        gp.add(new Label("Downloaded"), 0, 5);
        gp.add(tfDownloaded, 1, 5);

        gp.setHgap(4);
        gp.setVgap(8);

        VBox.setVgrow(gp, Priority.ALWAYS);
        VBox.setMargin(gp, new Insets(40));

        ButtonBar buttonBar = new ButtonBar();
        ButtonBar.setButtonData(downloadButton, ButtonBar.ButtonData.OTHER);
        buttonBar.getButtons().add(downloadButton);
        buttonBar.setPadding(new Insets(10d));

        VBox vBox = new VBox(
                gp,
                new Separator(),
                buttonBar
        );

        initBindings();

        downloadButton.setOnAction(event -> downloaded.set(true));
        downloaded.addListener((observable, oldValue, newValue) -> currentTrack.setDownloaded(true));

        Scene scene = new Scene(vBox);
        scene.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.D) {
                System.out.println(currentTrack);
            }
        });

        primaryStage.setScene(scene);
        primaryStage.setTitle("BindingSelectApp");
        primaryStage.show();
    }

    private void initBindings() {
        tfArtist.textProperty().bind(Bindings.select(currentTrack, "artist"));
        tfAlbum.textProperty().bind(Bindings.select(currentTrack, "album"));
        tfTrack.textProperty().bind(Bindings.select(currentTrack, "track"));

        tfTrackNo.textProperty().bind(Bindings.select(currentTrack, "trackNo").asString());
        tfRating.textProperty().bind(
                Bindings.concat(
                        Bindings.select(currentTrack, "rating", "value").asString(),
                        " out of ",
                        Bindings.select(currentTrack, "rating", "scale").asString()
                )
        );

        tfDownloaded.textProperty().bind(downloaded.asString());
        downloadButton.disableProperty().bind(downloaded);
    }
}
